﻿#pragma once
#include "_private/_privateinc.h"
#include "_private/_privateutil.hpp"
#include "logbase.h"

#ifdef _WIN32
#include <windows.h>
#endif

NAMESPACE_BEG


#define RESET   "\033[0m"
#define RED     "\033[31m" /* Red */
#define GREEN   "\033[32m" /* Green */
#define YELLOW  "\033[33m" /* Yellow */
#define BLUE    "\033[34m" /* Blue */
#define MAGENTA "\033[35m" /* Magenta */
#define WHITE   "\033[37m" /* White */
#define MAGENTA "\033[35m" /* Magenta  fatal*/

class LoggerConslPrintter {

public:
    static LoggerConslPrintter& getInstance() {
        static LoggerConslPrintter printer;
        return printer;
    }
    ~LoggerConslPrintter()
    {

    }
    inline void setDisplayFormat(int format) { format_= format; }
private:
    LoggerConslPrintter()
    {
#ifdef _WIN32
        hand_conls_ = GetStdHandle(STD_OUTPUT_HANDLE);
#endif
    }
    
    

    void  __setLogFormat(const LogItem& logger) {
        std::stringstream ss;
        if (format_& LOG_FORMAT::DIS_LOG_LEVEL) {
            switch (logger.property_.level_)
            {
            case LOG_LEVEL::FAT: {
                ss << "[FAT]";
                break;
            }
            case LOG_LEVEL::WAR: {
                ss << "[WAR]";
                break;
            }
            case LOG_LEVEL::INF: {
                ss << "[INF]";
                break;
            }
            case LOG_LEVEL::ERR: {
                ss << "[ERR]";
                break;
            }
            case LOG_LEVEL::BUG: {
                ss << "[DEBUG]";
                break;
            }
            }
        }
        if (format_ & LOG_FORMAT::DIS_FILE) {
            ss << "[" << logger.property_.file_ << "]";
        }
        if (format_ & LOG_FORMAT::DIS_THID) {
            ss << "[" << logger.property_.thread_id_ << "]";
        }
        ss << "[";
        if (format_ & LOG_FORMAT::DIS_FUN) {
            ss << logger.property_.func_ << ":";
        }
        if (format_ & LOG_FORMAT::DIS_LIN) {
            ss << logger.property_.line_;
        }
        ss << "]";
        if (format_ & LOG_FORMAT::DIS_TIME) {
            ss << "[" << serilTimeToStr(logger.property_.time_) << "] ";
        }
        prefix_str_ = std::move(ss.str());
    }
    void __setLogColor(const LogItem& logger)
    {

#ifdef _WIN32
        if (!hand_conls_)
            return;

        switch (logger.property_.level_) {
        case LOG_LEVEL::INF: {
            SetConsoleTextAttribute(hand_conls_, FOREGROUND_GREEN);
            break;
        }
        case LOG_LEVEL::WAR: {
            SetConsoleTextAttribute(hand_conls_, FOREGROUND_GREEN | FOREGROUND_RED);
            break;
        }
        case LOG_LEVEL::ERR: {
            SetConsoleTextAttribute(hand_conls_, FOREGROUND_RED);
            break;
        }
        case LOG_LEVEL::BUG: {
            break;
        }
        case LOG_LEVEL::FAT: {
            SetConsoleTextAttribute(hand_conls_, FOREGROUND_RED | BACKGROUND_BLUE);
            break;
        }
        }
#else
        std::stringstream ss;
        switch (logger.property_.level_) {
        case LOG_LEVEL::INF: {
            ss << GREEN << prefix_str_;
            break;
        }
        case LOG_LEVEL::WAR: {
            ss << YELLOW << prefix_str_;
            break;
        }
        case LOG_LEVEL::ERR: {
            ss << RED << prefix_str_;
            break;
        }
        case LOG_LEVEL::FAT: {
            ss << MAGENTA << prefix_str_;
            break;
        }
        case LOG_LEVEL::BUG:
        {
            ss << prefix_str_;
            break;
        }
        }
        prefix_str_ = std::move(ss.str());
#endif
    }



public:
    void print(const LogItem& loger)
    {
        __setLogFormat(loger);
        __setLogColor(loger);
#ifdef WIN32
        std::cerr << prefix_str_ << loger.log_ << std::endl;
#else
        std::cerr << prefix_str_ << loger.log_ << RESET << std::endl;
#endif

#ifdef WIN32
        if (hand_conls_)
            SetConsoleTextAttribute(hand_conls_, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED);
#endif

    }


private:
    int format_=126;
#ifdef _WIN32
    HANDLE hand_conls_;
#endif

    str_t  prefix_str_;
};



NAMESPACE_END
